//
//  ViewControllerOne.m
//  文件下载的断点续传
//
//  Created by Xie Wei on 2019/7/11.
//  Copyright © 2019 谢伟. All rights reserved.
//

#import "ViewControllerOne.h"

@interface ViewControllerOne () <NSURLConnectionDataDelegate>

@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (nonatomic, strong) NSURLConnection *connection;
// 沙盒路径
@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, strong) NSString *fileName;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;

@property (nonatomic, strong) NSFileHandle *handle;

@end

@implementation ViewControllerOne

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"通过句柄实现断点续传";
}

- (IBAction)startDownloadAction:(UIButton *)sender {
    [self download];
}

- (IBAction)cancelDownloadAction:(UIButton *)sender {
    [self.connection cancel];
}

- (IBAction)goOnDownloadAction:(UIButton *)sender {
    [self download];
}

- (void)download {
    NSString *urlString = [@"https://desk-fd.zol-img.com.cn/t_s2880x1800c5/g2/M00/0A/08/ChMlWl0etgeIBDlZABHLgESTo1gAALjkAAAAAAAEcuY500.jpg" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url = [NSURL URLWithString:urlString];
    // 创建请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 设置请求头信息，告诉服务器值请求一部分数据的range
    /*
     设置请求头信息有固定格式
     eg：
     表示头500个字节：Range： bytes=0-499
     表示第二个500字节：Range： bytes=500-999
     表示最后500个字节：Range： bytes=-500
     表示500个字节以后的范围：Range： bytes=500-
     */
    NSString *range = [NSString stringWithFormat:@"bytes=%zd-", self.currentSize];
    [request setValue:range forHTTPHeaderField:@"Range"];
    // 发送请求
    /*
     参数1: 文件路径
     参数2: YES 追加
     特点：如果该输出流指向的地址没有文件，那么会自动创建一个空文件
     */
    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

#pragma mark - NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"%s", __func__);
    // 得到文件的总大小
    // 注：本次请求的文件数据的总大小 不等于 文件的总大小
    self.totalSize = self.currentSize + response.expectedContentLength;
    
    if (self.currentSize > 0) {
        return;
    }
    
    // 根据响应头的信息获得推荐的文件名称
    // suggestedFilename: 服务器端推荐的名称，其实就是URL的最后一个节点
    self.fileName = response.suggestedFilename;
    
    // 获得caches目录
    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    
    // 拼接全路径
    self.fullPath = [caches stringByAppendingPathComponent:self.fileName];
    
    // 新建一个空的文件
    /*
     参数1: 文件的路径
     参数2: 文件的内容
     参数3: 文件的属性
     */
    [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
    
    // 创建文件句柄
    self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    //    NSLog(@"%s", __func__);
    
    // 移动文件句柄到文件末尾
    [self.handle seekToEndOfFile];
    
    // 写数据到磁盘
    [self.handle writeData:data];
    
    // 获得进度
    self.currentSize += data.length;
    
    NSLog(@"%f", 1.0 * self.currentSize / self.totalSize);
    self.progressView.progress = 1.0 * self.currentSize / self.totalSize;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"%s", __func__);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"%@", self.fullPath);
    NSLog(@"%s", __func__);
    
    // 释放文件句柄
    [self.handle closeFile];
    self.handle = nil;
}

@end
